
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Cesium3DTilesSelection;
using Unity.Mathematics;
using System.Linq;
using EarthGeospatial;

public class CesiumGeoreference : MonoBehaviour
{
    private double[] _ellipsoidRadii;
    private GeoTransforms _geoTransforms;
    private bool _insideSublevel;
    EOriginPlacement OriginPlacement = EOriginPlacement.CartographicOrigin;
    public event Action OnGeoreferenceUpdated;

    [Header("经度 [-180  +180")]
    public double OriginLongitude;
    [Header("纬度 [-90  +90]")]
    public double OriginLatitude;
      [Header("高度")]
    public double OriginHeight;

    private void Awake()
    {
        var radii = EarthGeospatial.Ellipsoid.WGS84.getRadii();
        _ellipsoidRadii = new double[] { radii.x, radii.y, radii.z };
        _insideSublevel = false;
        this._geoTransforms = new GeoTransforms();
        _updateGeoTransforms();
    }
    private void Start()
    {
        UpdateGeoreference();
    }

    internal GeoTransforms GetGeoTransforms()
    {
        return _geoTransforms;
    }

    public void UpdateGeoreference()
    {
        this._updateGeoTransforms();
        OnGeoreferenceUpdated?.Invoke();
    }

    private void _updateGeoTransforms()
    {
        double3 center = new double3(0.0, 0.0, 0.0);
        if (this.OriginPlacement == EOriginPlacement.CartographicOrigin)
        {
            center = _geoTransforms.TransformLongitudeLatitudeHeightToEcef(new double3(this.OriginLongitude, this.OriginLatitude, this.OriginHeight));
        }

        this._geoTransforms = new GeoTransforms(new Ellipsoid(this._ellipsoidRadii[0], this._ellipsoidRadii[1], this._ellipsoidRadii[2]), center);
    }

    void PlaceGeoreferenceOriginHere()
    {
        /**
   * This aligns the specified longitude in degrees (x), latitude in
   * degrees (y), and height above the ellipsoid in meters (z) to Unreal's world
   * origin. I.e. it moves the globe so that these coordinates exactly fall on
   * the origin.
   *
   * When the WorldOriginCamera of this instance is currently contained
   * the bounds of a sublevel, then this call has no effect.
   */
        void SetGeoreferenceOrigin(double3 TargetLongitudeLatitudeHeight) { }
    }

    public static CesiumGeoreference GetDefaultGeoreference(Cesium3DTileset cesium3DTileset)
    {
        return cesium3DTileset.GetComponent<CesiumGeoreference>();
    }
}


enum EOriginPlacement
{
    /**
     * Use the tileset's true origin as the Actor's origin. For georeferenced
     * tilesets, this usually means the Actor's origin will be at the center
     * of the Earth, which is not recommended. For a non-georeferenced tileset,
     * however, such as a detailed building with a local origin, putting the
     * Actor's origin at the same location as the tileset's origin can be useful.
     */
    TrueOrigin,

    /**
     * Use a custom position within the tileset as the Actor's origin. The
     * position is expressed as a longitude, latitude, and height, and that
     * position within the tileset will be at coordinate (0,0,0) in the Actor's
     * coordinate system.
     */
    CartographicOrigin
};
